home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac100% 1998 November
/
MAC100-1998-11.ISO.7z
/
MAC100-1998-11.ISO
/
オンラインソフト定点観測
/
ユーティリティ
/
Mops 3.2.sea
/
Mops 3.2
/
Mops ƒ
/
zArgs
< prev
next >
Wrap
Text File
|
1998-06-20
|
10KB
|
404 lines
¥ zArgs - support for named parms and local variables
(* This file is the PPC equivalent of the 68k "Args" file. It's a
"z" file - it's not target compiled, but is loaded on the PPC itself.
Args has EVALUATE - the PPC EVALUATE has already been target compiled
in pArgs since we needed it earlier. Here we include everything else.
*)
11 constant MAXPL ¥ We can only spare 11 regs on PPC,
¥ or 10 if we use I (r21).
false value LOCFLG ¥ true = looking for local var tokens
0 value LOC_ADDR
create PARMLIST maxPL cells 8 + reserve
create FPARMLIST maxPL cells 8 + reserve
0 value SVHASH
false value FLOAT?
0 value PLentry_addr
: INITLOCS ¥ Initializes flags etc.
0 -> #PL 0 -> #P 0 -> #FPL 0 -> #FP
0 -> FltFlg false -> locFlg ;
: FINDINPARMLIST ¥ ( addr -- loc# T OR -- F )
¥ loc# counts from right to left in the local/parm list.
dup 1+ c@ & % = -> float?
hash -> svHash false
float?
IF #FPL 0EXIT fparmlist #FPL
ELSE #PL 0EXIT parmlist #PL
THEN
4* bounds
DO svHash i @ =
IF ( found )
drop
float?
IF #FPL i fparmlist -
ELSE #PL i parmlist -
THEN
4/ - 1- true LEAVE
THEN
4 +LOOP ;
: ADDTOPARMLIST ¥ ( addr -- ) Adds an element to parmList.
¥ addr points to a counted string.
findinParmList ?error 95 ¥ Name not unique
#PL maxPL > ?error 110 ¥ too many parms/locals
svHash
float?
IF #FPL 1 ++> #FPL 4* fParmlist + !
locFlg NIF 1 ++> #FP THEN
ELSE #PL 1 ++> #PL 4* parmlist + !
locFlg NIF 1 ++> #P THEN
THEN
;
: FIRSTCHR ( -- c )
inline{ CDP 1+ c@} ;
0 value testxxx
:f {
local? IF ¥ local? already non-zero - this ought to mean we're
¥ in a local section
local? 0< ?error 92 -1 -> local?
THEN
initLocs
BEGIN ¥ Loop to add parms/locals to parmlist
Mword drop
firstChr & - <> ¥ look for --
WHILE
firstChr dup & ¥ = swap & / = or
¥ Note: we allow / as an alternative to ¥ in this context,
¥ since it's an easy mistake to make, and / isn't a
¥ sensible parm name since it already has a meaning.
IF true -> locFlg
ELSE firstChr & } = ?error 111
CDP addToParmList
THEN
REPEAT
local? NIF ¥ In local sections, we do this at :LOC
CDP -> PLentry_addr
¥ If we have temp objects, we'll have to backup the DP and
¥ recompile the entry sequence, since there'll be an extra local
¥ (the frame pointer)
PLentry
THEN
BEGIN ¥ Loop gobble chars until }
Mword drop
firstChr & } = ¥ look for }
UNTIL
;f
¥ FIND will call the forward-defined initFind first, to attempt to find
¥ a name. At this stage in building the system we need to look for
¥ named parms & locals, so we define a word pFind which looks for them,
¥ and resolve initFind to pFind. Later we'll re-resolve initFind to look
¥ for selectors, etc. as well as calling pFind.
¥ If pFind finds the name is a parm/local, it returns true and the
¥ cfa of LocParm, which is a dummy word whose handler compiles
¥ a local reference.
: PFIND ¥ ( str-addr -- cfa T | -- str-addr F )
state NIF false EXIT THEN
#PL #FPL or NIF false EXIT THEN
dup findInParmList NIF false EXIT THEN
¥ found it!
-> loc# drop
float? IF <'> FlocParm ELSE <'> locParm THEN
true
;
:f initFind pFind ;f
: ,EXEC ¥ ( cfa n -- )
state
IF (compN) ELSE exN THEN ;
¥ Here are the different types that we can put prefixes on or send
¥ messages to:
enum{ notfnd locTyp flocTyp
tmpObjTyp objTyp ivarTyp classTyp superTyp
valTyp fvalTyp vecTyp dynVecTyp objptrTyp
regTyp lbTyp lbSelfTyp bktTyp wordTyp }
(* notFnd - not previously defined
locTyp - a local or named parm
tmpObjTyp - a temporary (local) object
objTyp - an object
ivarTyp - an ivar
classTyp - a class
superTyp - a named superclass specified by msg: super> someClass
valTyp - a value
FvalTyp - a floating point value
vecTyp - a vector
dynVecTyp - a dynamic vector
regTyp - a 680x0 register
lbTyp - ** or [] meaning late bind
lbSelfTyp - [self] meaning late bind to self
BktTyp - [ - Neon-compatible late bind
wordTyp - a word
*)
: HDLR ( xt - handler_code )
inline{ 2- w@} ;
¥ PRFTOKEN returns the type of a token for a prefix op.
: PRFTOKEN ¥ ( -- cfa type )
' dup <'> locParm = IF locTyp EXIT THEN
dup <'> FlocParm = IF FlocTyp EXIT THEN
dup hdlr
CASE
$ BC03 OF valTyp ENDOF
$ BC27 OF FvalTyp ENDOF
$ BC05 OF vecTyp ENDOF
$ BC3D OF vecTyp ENDOF ¥ sVect
$ BC3B OF dynVecTyp ENDOF
$ BD0A OF regTyp ENDOF
$ BC1F OF objPtrTyp ENDOF
114 die
ENDCASE ;
forward ToObjPtr ¥ Stores to an objPtr. Defined in file Class.
: ->
prfToken ¥ All types are legal
objPtrTyp = IF toObjPtr EXIT THEN
$ 60 ( opcode for Store ) ,exec
; immediate ¥ NOTE: opcode for store hard coded here!!!
: CvrtFcode ¥ ( code -- code' )
CASE
$ 21 OF $ 41 ENDOF ¥ +
$ 22 OF $ 48 ENDOF ¥ -
$ 28 OF $ 55 ENDOF ¥ Neg
?error 114
ENDCASE ;
: (+->) ¥ ( code -- cfa code' )
PrfToken ( code cfa type ) rot swap ( cfa code type )
CASE
locTyp OF ENDOF
FlocTyp OF cvrtFcode ENDOF
valTyp OF ENDOF
FvalTyp OF cvrtFcode ENDOF
regTyp OF ENDOF
?error 114
ENDCASE ;
: (FOP)
PrfToken rot swap
CASE
locTyp OF ENDOF
FlocTyp OF ENDOF
FvalTyp OF ENDOF
?error 114
ENDCASE ;
¥ Note: the following opcodes have to agree with the definitions in
¥ OD.asm. I could have defined them as constants but this would have
¥ used up dictionary space for no great benefit.
: ++> $ 21 (+->) ,exec ; immediate
: +> postpone ++> ; immediate ¥ A synonym.
: --> $ 22 (+->) ,exec ; immediate
: AND> $ 23 (+->) ,exec ; immediate
: OR> $ 24 (+->) ,exec ; immediate
: XOR> $ 25 (+->) ,exec ; immediate
: NEG> $ 28 (+->) ,exec ; immediate
: NOT> $ 29 (+->) ,exec ; immediate
: *> $ 42 (fop) ,exec ; immediate
: /> $ 49 (fop) ,exec ; immediate
: ABS> $ 54 (fop) ,exec ; immediate
¥ ' Pfind -> Ufind
¥ =========== Local sections ===========
forward INITTEMPS
: ?LOC local? 0= ?error 91 ; ¥ "We're not in a local section"
: LOCAL
local? ?error 93 1 -> local? ¥ We change it to the normal -1
¥ as soon as "{" is read.
CDP -> CD_gpr_loc
forward ¥ LOCAL is just like FORWARD
CDP 4- -> loc_addr
;
: :LOC
local? 1 = IF msg# 96 THEN ¥ warning - no locals defined
?loc
' drop ¥ gobble word name
CDP -> const_data_start ¥ the following is like :f (see qpCond)
$ BE020000 code, ¥ marks this as the :loc position
¥ (just for disassembly)
false -> method?
false -> local? ¥ so entry sequence gets compiled
true ppc_entry ¥ handle ppc proc entry. We're handling
¥ local sections by calling FORWARD,
¥ so we need to tell ppc_entry this
¥ is a forward defn so the parms get
¥ handled properly.
fwd_gpr_rtn_cnt -> gpr_rtn_cnt
fwd_fpr_rtn_cnt -> fpr_rtn_cnt
drop 304 ¥ security marker for :loc
curr-def
loc_addr -> curr-def
PLentry
-> curr-def
tempObj_frameSize IF initTemps THEN
; immediate
: ;LOC
304 ?defn
false -> leaf? ¥ let's just reduce the bug possibilities!
loc_addr 2- (;)
loc_addr curr-def resolve_unconditional_branch
¥ finally resolve the forward branch
¥ from LOCAL
; immediate
¥ ============================================
¥ EVALUATE was already loaded in pArgs, along with the value compinline?.
: (COMPINL) ¥ ( xt -- )
true -> compinline?
2+ count evaluate
false -> compinline? ;
' (compinl) -> compinline
: [IF] { flag ¥ addr len level done? -- }
flag ?EXIT
false -> done? 1 -> level
BEGIN
Mword count -> len -> addr
addr len " [THEN]" s= IF 1 --> level
ELSE addr len " [ELSE]" s= IF level 1 =
IF true -> done? THEN
ELSE addr len " [IF]" s= IF 1 ++> level
THEN THEN THEN
level NIF true -> done? THEN
done?
UNTIL
; immediate
: [ELSE] { ¥ addr len level done? -- }
false -> done? 1 -> level
BEGIN
Mword count -> len -> addr
addr len " [THEN]" s= IF 1 --> level
ELSE addr len " [IF]" s= IF 1 ++> level
THEN THEN
level NIF true -> done? THEN
done?
UNTIL
; immediate
: [THEN] ; immediate
(* INSTEAD ( c-old c-new -- ) may be used just after a SCON is defined.
Within the SCON, it replaces any occurrences of c-old with c-new. This
operation is useful for creating SCONs containing special characters
such as tab.
This logically should come after SCON in zBase, but it needs locals
so we'll put it here.
*)
: INSTEAD { c-old c-new -- }
latest name> ex-gen bounds ¥ SCONs use DOES> so require EX-GEN
DO i c@ c-old = IF c-new i c! THEN
LOOP ;
¥ =============================
¥ ASSERTIONS
¥ =============================
(* Assertions allow you, during development, to ensure that
things are the way they're supposed to be at key places.
Usage:
ASSERT{ <something that evaluates to a flag> }
If ASSERTIONS? is true, this will give error 216 ("assertion failed")
if the evaluated flag is false. If ASSERTIONS? is false, nothing
will happen - the code between ASSERT{ and } isn't executed.
ASSERTIONS? can be defined and redefined however and whenever you
like, as long as it returns a flag - ASSERT{ tests it via EVALUATE,
so the latest definition will always be the one that gets looked at.
If you have ASSERTIONS? defined as a constant with value false, no
code will even be compiled for the assertion test - you can use this
for code that you know works.
*)
false constant assertions? ¥ redefine however and whenever necessary
: }ASSERT
134 ?pairs
['] } >body !
" NIF 216 die THEN THEN" evaluate ¥ assertion failed!
; immediate
: ASSERT{
?comp
" assertions? if" evaluate
['] } >body @ ¥ save old action for "}"
['] }assert -> } ¥ "}" will now be same as }assert
134
; immediate